﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Blizzard.Contracts ;
using Blizzard.Container ;

namespace Blizzard
{

    /// <summary>
    /// This class is a kind of Flow collection for the whole solution.
    /// Flows in this class will be used in different places. They do not
    /// have necessarilly any logical connection with eachother.
    /// Also, not all the flows in this solution will be find here
    /// </summary>
    internal class Flows
    {

        internal static void Flow_ObjectDeleteMarker(IDataObject mainObject)
        {

            List<RelationInstance> ris = RelationInstanceContainer.GetAllRelations(mainObject);

            foreach (RelationInstance ri in ris)
            {
                if(ri.Status != RelationStatus.Broken)
                Flow_BreakOrRemoveRelation(ri);
            }

            if (mainObject.Id == 0)
            {//R1
                NewObjectContainer.RemoveFromContainer(mainObject);
            }
            else
            {//L1
                DBObjectContainer.MarkForDeletion(mainObject);
            }

        }

        internal static void Flow_BreakOrRemoveRelation(RelationInstance ri)
        {

            if (ri.Rd.Relation == RelationSort.OneToManyComposition)
            {//L1

                //Getting the child object============

                IDataObject childObject = ri.GetChild();

                //==================================

                if (ri.Obj1.Id != 0 && ri.Obj2.Id != 0)
                {//L2
                    RelationInstanceContainer.BreakTheRelationShip(ri);
                }
                else
                {//L3
                    RelationInstanceContainer.RemoveFromContainer(ri);
                }

                Flow_ObjectDeleteMarker(childObject);
            }
            else
            {//R1

                if (ri.Obj1.Id != 0 && ri.Obj2.Id != 0)
                {//R2
                    RelationInstanceContainer.BreakTheRelationShip(ri);
                }
                else
                {//R3
                    RelationInstanceContainer.RemoveFromContainer(ri);
                }

            }
        }

        internal static void Flow_BListSetterRelationCreator(IDataObject mainObject, IDataObject associate)
        {

            Type parentType = RelationDefinitionContainer.GetParentType(mainObject.GetType(), associate.GetType());
         
            RelationDefinition rd = RelationDefinitionContainer.GetRd(mainObject.GetType(), associate.GetType());

            if (parentType != null && (rd.Relation == RelationSort.OneToMany || rd.Relation == RelationSort.OneToManyComposition))
            {//L1


                if (RelationInstanceContainer.HasAlreadyOneParent(associate, parentType))
                {//L2

                    List<RelationInstance> relations =
                        RelationInstanceContainer.GetAllRelations(associate, parentType);

                    RelationInstance ri = relations[0];


                    if (ri.Obj1.Id == 0 || ri.Obj2.Id == 0)
                    {//L3
                        RelationInstanceContainer.RemoveFromContainer(ri);
                    }
                    else
                    {//L4
                        RelationInstanceContainer.BreakTheRelationShip(ri);
                    }

                }

            }

            RelationInstanceContainer.CreateNewRelationShip(mainObject, associate);
        }


    }
}
